package com.qzsoft.bootstrap.aspect;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.qzsoft.jeemis.platform.security.user.SecurityUser;
import com.qzsoft.jeemis.platform.security.user.UserDetail;
import com.qzsoft.zhjd.common.annotation.ZhjdDataFilter;
import com.qzsoft.zhjd.common.enums.BizCode;
import com.qzsoft.zhjd.common.utils.RenExceptionUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * @ClassName ZhjdDataFilterAspect
 * @Description 数据权限拦截器
 * @author linhuawei
 * @since 2022-01-07
 */
@Slf4j
@Aspect
@Component
public class ZhjdDataFilterAspect {

    @Pointcut("@annotation(com.qzsoft.zhjd.common.annotation.ZhjdDataFilter)")
    public void pointCut() {
    }

    @Before("pointCut()")
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public void dataFilter(JoinPoint point) throws Throwable {
        // 判断是否有用户信息
        UserDetail user = SecurityUser.getUser();
        if (null == user) {
            log.info("不需要进行数据权限校验");
            return;
        }

        // 获取当前用户基地编号
        List<String> baseCodes = user.getDeptIdList();
        if (null == baseCodes || 0 == baseCodes.size()) {
            log.info("未设置数据权限，默认全部权限");
            return;
        }

        // 获取注解信息
        MethodSignature signature = (MethodSignature) point.getSignature();
        ZhjdDataFilter zhjdDataFilter = signature.getMethod().getAnnotation(ZhjdDataFilter.class);
        String tableAlias = zhjdDataFilter.tableAlias();
        String baseCode = zhjdDataFilter.baseCode();
        if (ObjectUtils.isNotEmpty(tableAlias)) {
            baseCode = tableAlias + "." + baseCode;
        }

        // 获取第一个参数
        Object params = point.getArgs()[0];
        if (null == params) {
            RenExceptionUtils.throwEx(BizCode.EXCEPTION, "数据权限接口，至少有一个参数，并且不可为null");
        } else if (params instanceof Map) {
            Map map = (Map) params;
            map.put(ZhjdDataFilter.DATA_FILTER_PARAMS, baseCodes);
            StringBuffer sql = new StringBuffer(" ");
            sql.append(baseCode);
            sql.append(" IN (");
            for (int i = 0, len = baseCodes.size(); i < len; i++) {
                if (0 < i) {
                    sql.append(",");
                }
                sql.append("'");
                sql.append(baseCodes.get(i));
                sql.append("'");
            }
            sql.append(") ");
            map.put(ZhjdDataFilter.DATA_FILTER_SQL, sql.toString());
        } else if (params instanceof QueryWrapper) {
            QueryWrapper queryWrapper = (QueryWrapper) params;
            queryWrapper.in(baseCode, baseCodes);
        } else {
            Field declaredField = params.getClass().getDeclaredField(ZhjdDataFilter.DATA_FILTER_SQL);
            if(declaredField == null){
                RenExceptionUtils.throwEx(BizCode.EXCEPTION, "数据权限接口，参数必须为Map或QueryWrapper");
            }else {
                declaredField.setAccessible(true);
                StringBuffer sql = new StringBuffer(" ");
                sql.append(baseCode);
                sql.append(" IN (");
                for (int i = 0, len = baseCodes.size(); i < len; i++) {
                    if (0 < i) {
                        sql.append(",");
                    }
                    sql.append("'");
                    sql.append(baseCodes.get(i));
                    sql.append("'");
                }
                sql.append(") ");
                declaredField.set(params,sql.toString());
            }
        }
    }
}
